package com.cskaoyan.service.impl;

import com.cskaoyan.bean.*;
import com.cskaoyan.bean.Cart;
import com.cskaoyan.bean.CartExample;
import com.cskaoyan.bean.vo.CartCouponVo;
import com.cskaoyan.mapper.CouponMapper;
import com.cskaoyan.mapper.CouponUserMapper;
import com.cskaoyan.mapper.CartMapper;
import com.cskaoyan.service.CouponService;
import com.cskaoyan.utils.*;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Description
 * 优惠卷实现类
 *
 * @author Zhangfei
 * @date Created on 2021/10/19
 */
@Service
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class CouponServiceImpl implements CouponService {


    @Autowired
    CouponMapper couponMapper;

    @Autowired
    CouponUserMapper couponUserMapper;

    @Autowired
    CartMapper cartMapper;


    /**
     * 通过分页条件查询优惠卷
     *
     * @param name
     * @param type
     * @param status
     * @param param
     * @return
     */
    @Override
    public BasePageData list(String name, Integer type, Integer status, BaseParam param) {
        //配置分页信息
        PageHelper.startPage(param.getPage(), param.getLimit());

        //构造查询条件
        CouponExample example = new CouponExample();
        //根据参数判断是否为null，不为null则拼接条件
        CouponExample.Criteria criteria = example.createCriteria();
        if (CommonUtil.isStrNotEmpty(name)) {
            criteria.andNameLike("%" + name + "%");
        }
        if (type != null) {
            criteria.andTypeEqualTo(type);
        }
        if (status != null) {
            criteria.andStatusEqualTo(status);
        }
        criteria.andDeletedEqualTo(false);

        //添加排序条件
        example.setOrderByClause(param.getSort() + " " + param.getOrder());
        //查询
        List<Coupon> coupons = couponMapper.selectByExample(example);
        return BasePageData.ok(coupons);
    }


    /**
     * 通过id查询优惠卷
     *
     * @param id
     * @return
     */
    @Override
    public Coupon read(Integer id) {
        Coupon coupon = couponMapper.selectByPrimaryKey(id);
        return coupon;
    }

    /**
     * 通过优惠卷id查询拥有该优惠卷的用户
     *
     * @param status
     * @param userId
     * @param couponId
     * @param param
     * @return
     */
    @Override
    public BasePageData getUserByCouponId(Integer userId, Integer couponId, Integer status, BaseParam param) {
        //配置分页信息
        PageHelper.startPage(param.getPage(), param.getLimit());

        //构造查询条件
        CouponUserExample example = new CouponUserExample();
        //根据参数判断是否为null，不为null则拼接条件
        CouponUserExample.Criteria criteria = example.createCriteria();
        if (couponId != null) {
            criteria.andCouponIdEqualTo(couponId);
        }
        if (userId != null) {
            criteria.andUserIdEqualTo(userId);
        }
        if (status != null) {
            criteria.andStatusEqualTo(status);
        }
        criteria.andDeletedEqualTo(false);

        //添加排序条件
        example.setOrderByClause(param.getSort() + " " + param.getOrder());
        //查询
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(example);
        return BasePageData.ok(couponUsers);
    }

    /**
     * 删除优惠卷
     *
     * @param coupon
     * @return
     */
    @Override
    public Integer delete(Coupon coupon) {
        //设置修改时间
        coupon.setUpdateTime(new Date());
        //如果是普通的删除则是下架，状态为2则下架
        if (coupon.getStatus() != 2) {
            coupon.setStatus(2);
        } else {
            coupon.setDeleted(true);
        }
        //然后删除所有拥有该用户卷的用户
        CouponUserExample couponUserExample = new CouponUserExample();
        CouponUserExample.Criteria criteria = couponUserExample.createCriteria();
        CouponUser couponUser = new CouponUser();
        couponUser.setDeleted(true);
        couponUser.setUpdateTime(new Date());
        criteria.andCouponIdEqualTo(coupon.getId());
        //执行
        couponUserMapper.updateByExampleSelective(couponUser, couponUserExample);
        //执行
        return couponMapper.updateByPrimaryKeySelective(coupon);

    }

    /**
     * 修改优惠卷
     */
    public Coupon updateOrCreate(Coupon coupon) {
        //如果是可兑换优惠卷则生成8位兑换码
        if (coupon.getType() != null && coupon.getType() == 2) {
            coupon.setCode(RandomUtil.GetRandomString(8).toUpperCase());
        }

        if (coupon.getDays() != null && coupon.getDays() >= 0) {
            //如果只设置了天数则手动添加时间
            Date startTime = new Date();
            //结束时间
            Date endTime = DateUtil.getAddDate(startTime, coupon.getDays());
            coupon.setStartTime(startTime);
            coupon.setEndTime(endTime);
        } else {
            //说明输入的时间则添加天数
            Integer days = DateUtil.getDiffDays(coupon.getStartTime(), coupon.getEndTime());
            coupon.setDays(days);
        }
        //根据优惠卷类型设置,如果是新人注册卷
        if (coupon.getType() == 1) {
            coupon.setLimit(1);
            coupon.setEndTime(DateUtil.getAddDate(new Date(), 1));
        }
        if (coupon.getTag() == null) {
            coupon.setTag(CouponTagUtil.getValue(coupon.getType()));
        }
        return coupon;
    }

    /**
     * 添加优惠卷
     *
     * @param coupon
     * @return
     */
    @Override
    public Coupon create(Coupon coupon) {
        //设置插入以及更新时间
        coupon.setAddTime(new Date());
        coupon.setUpdateTime(new Date());
        //修改优惠卷
        coupon = updateOrCreate(coupon);
        Integer count = couponMapper.insertSelective(coupon);
        //根据返回的主键查询专题再响应回去
        Coupon couponToReturn = null;
        if (count != 0) {
            couponToReturn = couponMapper.selectByPrimaryKey(coupon.getId());
        }
        return couponToReturn;
    }


    /**
     * 更新优惠卷详情
     *
     * @param coupon
     * @return
     */
    @Override
    public Coupon update(Coupon coupon) {
        //设置更新时间
        coupon.setUpdateTime(new Date());
        //修改优惠卷
        coupon = updateOrCreate(coupon);

        //如果结束时间大于现在，则改为可以领取，否则改为已过期
        if (DateUtil.compareDate(coupon.getEndTime(), new Date()) > 0) {
            coupon.setStatus(0);
        } else {
            coupon.setStatus(1);
        }
        couponMapper.updateByPrimaryKeySelective(coupon);

        //执行
        Coupon couponToReturn = couponMapper.selectByPrimaryKey(coupon.getId());
        return couponToReturn;
    }


    /**
     * 提取公公该改变优惠卷数量和拥有该优惠卷的用户
     *
     * @param userId
     * @param coupon
     * @return
     */
    private Integer changeCoupon(Integer userId, Coupon coupon) {
        Integer couponId = coupon.getId();
        //查询该用户有没有领卷,以及和优惠卷数量限制
        CouponUserExample example = new CouponUserExample();
        CouponUserExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andCouponIdEqualTo(couponId);
        List<CouponUser> couponUsers = couponUserMapper.selectByExample(example);


        //如果领卷了或者领取卷数量高于优惠卷限制则返回已经领卷，
        if (couponUsers != null && coupon.getLimit() != 0 && couponUsers.size() >= coupon.getLimit()) {
            return Constant.COUPON_RECEIVED;
        }

        //如果没有道到数量要求或者没有领卷则领卷
        Coupon toChangeCoupon = couponMapper.selectByPrimaryKey(couponId);

        //如果可以领取则在用户优惠卷表添加数据
        if (coupon.getTotal() >= 0) {
            if (coupon.getTotal() != 0) {
                coupon.setTotal(coupon.getTotal() - 1);
            }
            coupon.setUpdateTime(new Date());
            couponMapper.updateByPrimaryKey(coupon);
            //赋值,在coupon_user表中添加数据
            CouponUser couponUser = new CouponUser();
            couponUser.setUserId(userId);
            couponUser.setCouponId(couponId);
            couponUser.setStatus(0);
            couponUser.setStartTime(toChangeCoupon.getStartTime());
            couponUser.setEndTime(toChangeCoupon.getEndTime());
            couponUser.setAddTime(new Date());
            couponUser.setUpdateTime(new Date());
            couponUser.setDeleted(false);

            //插入
            int count = couponUserMapper.insertSelective(couponUser);
            //如果领取成功成功则减少优惠卷数量,同时判断优惠卷数量
            if (count != 0) {
                return Constant.SUCCESS;
            }
        }

        return Constant.FAIL;
    }

    /**
     * 用户领取优惠卷
     *
     * @param couponId
     * @param userId
     * @return
     */
    @Override
    public Integer receive(Integer couponId, Integer userId) {
        //查看优惠卷详情
        Coupon coupon = couponMapper.selectByPrimaryKey(couponId);
        if (coupon.getType() == 2) {
            return Constant.COUPON_ONLY_EXCHANGE;
        }
        return changeCoupon(userId, coupon);

    }

    /**
     * 根据优惠卷码兑换优惠卷
     *
     * @param userId
     * @param code
     * @return
     */
    @Override
    public Integer exchange(Integer userId, String code) {
        //查询有没有该优惠卷
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria couponExampleCriteria = couponExample.createCriteria();
        couponExampleCriteria.andCodeEqualTo(code);

        //执行查询
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);

        if (coupons != null && coupons.size() > 0) {
            return changeCoupon(userId, coupons.get(0));
        }
        return Constant.COUPON_CODE_FALUT;
    }

    /**
     * 根据用户id和优惠卷状态以及分页信息查询优惠卷详情
     *
     * @param userId
     * @param status
     * @param param
     * @return
     */
    @Override
    public BasePageData mylist(Integer userId, Integer status, BaseParam param) {
        //配置分页信息
        PageHelper.startPage(param.getPage(), param.getLimit());

        //通过条件查询优惠卷
        //通过用户所拥有的优惠卷查询优惠卷详情
        List<Coupon> coupons = couponMapper.selectCouponJoinCouponUser(userId, status);

        //返回值
        return BasePageData.ok(coupons);
    }

    /**
     * TODO 这里为草案，后面再写
     * 根据用户id和购物车id查询优惠卷
     *
     * @param userId
     * @param cartId
     * @return
     */
    @Override
    public BasePageData selectlist(Integer userId, Integer cartId) {
        // 根据条件查询购物车
        CartExample example = new CartExample();
        CartExample.Criteria criteria = example.createCriteria();
        criteria.andUserIdEqualTo(userId).andCheckedEqualTo(true);
        // 0代表查看该用户所有的购物车
        if (cartId > 0) {
            criteria.andUserIdEqualTo(cartId);
        }
        //执行
        List<Cart> carts = cartMapper.selectByExample(example);
        BasePageData basePageData = new BasePageData();
        //遍历根据购物车中的商品查询优惠卷
        if (carts != null && carts.size() > 0) {
            //查询用户目前还能用的优惠劵
            List<Coupon> coupons = couponMapper.selectCouponJoinCouponUser(userId, 0);
            List<CartCouponVo> couponsToUseList = new ArrayList<>();
            if (coupons != null && coupons.size() > 0) {
                //遍历优惠卷查看可以用于的商品
                for (Coupon coupon : coupons) {
                    //转为集合提高效率
                    List<Integer> goodsIdList = new ArrayList<>();
                    Integer[] goodsValue = coupon.getGoodsValue();
                    if (goodsValue != null && goodsValue.length > 0) {
                        goodsIdList = Arrays.asList(goodsValue);
                    }

                    //计算购物车中的可以用该优惠卷所有商品总价
                    double couldBeUsedCouponGoodsTotal = 0;
                    //记录购物车id
                    int cId = 0;
                    int couldBeUserd = 0;
                    //遍历购物车查看可以用于该商品的所有商品，长度为0说明是全场优惠卷
                    for (Cart cart : carts) {
                        if (goodsIdList.contains(cart.getGoodsId()) || goodsIdList.size() == 0) {
                            //可以该优惠卷商品总价相加
                            couldBeUsedCouponGoodsTotal += cart.getPrice() * cart.getNumber();
                            couldBeUserd++;
                        }
                        if (cartId == 0) {
                            cId = cart.getId();
                        }
                    }

                    //如果couldBeUsed>0说明可以使用，具体是否满足金额的
                    if (couldBeUserd > 0) {
                        //如果商品总额大于优惠卷总额则添加优惠卷记录为true否则为false
                        CartCouponVo cartCouponVo = new CartCouponVo();
                        cartCouponVo.setId(cId);
                        cartCouponVo.setCid(coupon.getId());
                        cartCouponVo.setName(coupon.getName());
                        cartCouponVo.setDesc(coupon.getDesc());
                        cartCouponVo.setTag(coupon.getTag());
                        if (coupon.getMin() != null) {
                            cartCouponVo.setMin(coupon.getMin().intValue());
                        }
                        if (coupon.getDiscount() != null) {
                            cartCouponVo.setDiscount(coupon.getDiscount().doubleValue());
                        }
                        cartCouponVo.setStartTime(coupon.getStartTime());
                        cartCouponVo.setEndTime(coupon.getEndTime());
                        cartCouponVo.setAvailable(false);

                        //商品总金额大于优惠卷金额说明可以用
                        if (couldBeUsedCouponGoodsTotal >= coupon.getMin().doubleValue()) {
                            cartCouponVo.setAvailable(true);
                        }
                        couponsToUseList.add(cartCouponVo);
                    }
                }
            }
            //如果可用的优惠卷不为null则传递回去
            if (couponsToUseList != null && couponsToUseList.size() > 0) {
                basePageData.setPage(1);
                basePageData.setLimit(couponsToUseList.size());
                basePageData.setPages(1);
                basePageData.setTotal(couponsToUseList.size());
                basePageData.setList(couponsToUseList);
            }

        }
        return basePageData;
    }

}
